package while_lang.ast;

import java.util.*;

/** Categoría sintáctica de las sentencias (statements) de While. Éstas son
 *  todas las construcciones del lenguaje que modifican (potencialmente) los 
 *  valores de las variables en el estado del programa. 
 *  Todas las clases que representan construcciones dentro de la categoria 
 *  deben heredar de esta clase.
 *  @author Leonardo Val.
 */
public abstract class Stmt {
	
	/** Retorna un texto que de ser pasado por el parser construiría el mismo AST. 
	 */
	public abstract String unparse();
	
	/** Calculates the numbers required for the Halstead complexity measures.
	 *  @see <http://en.wikipedia.org/wiki/Halstead_complexity_measures>
	 */
	public abstract void halteadNumbers(Map<String, Integer> operands, Map<String, Integer> operators);
	
	/** Genera una instancia aleatoria de Stmt. 
	 */
	public static Stmt generate(Random random, int min, int max) {
		int i = min > 0 ? random.nextInt(3) + 1 : 
			max > 0 ? random.nextInt(4) : 
			0;
		switch (i) {
			case 0: return Assignment.generate(random, min, max);
			case 1: return IfThenElse.generate(random, min, max); 
			case 2: return WhileDo.generate(random, min, max);
			default: return Sequence.generate(random, min, max);
		} 
	}
	
	/** Todos los nodos del AST se convierten a string con una representación
	 *  textual similar a las llamadas a los constructores.
	 */
	@Override public abstract String toString();
	
	/** Se debe implementar para poder usar los nodos del AST con estructuras
	 *  como HashMap y HashSet.
	 */
	@Override public abstract int hashCode();
	
	/** Se debe implementar para poder usar los nodos del AST con estructuras
	 *  de datos.
	 */
	@Override public abstract boolean equals(Object obj);
	
	public static void incrementarDiccionario(String key,Map<String, Integer> map){
		if (map.containsKey(key)) {
			map.put(key, map.get(key) + 1);
		} else {
			map.put(key, 1);
		}
	}
}
